// 元函数的形参就是模板参数列表
// 元函数的实参就是元函数被调用时的 真正类型(元数据)
// 元函数可以没有返回值，即不定义type
// 元函数没有传值，传引用的区别，也没有函数指针的概念
// 元函数可以返回多个返回值，这些值没有顺序关系，能够使用  "::"  任意获取
template <typename T1, typename T2>
struct meta_function
{
    typedef int type;            // 元函数返回的元数据类型
    static int const value = 10; // 元函数返回的元数据值
};

template <int T1, int T2> // 两个整数元数据
struct meta_func          // 元函数
{
    static const int value = T1 + T2; // 编译期计算整数之和
};

template <typename T1, typename T2>
struct MyType
{
    typedef T1 type;
};

/**
 * 返回一个MyType<T_1, T_2>::type类型的返回值
 */
template <typename T_1, typename T_2, typename T3>
typename MyType<T_1, T_2>::type test_typename_return_type()
{
    T_1 a;
    return a;
}

/**
 * 元函数转发,相当于运行时的函数转发调用，使用了类继承
 * 子类会自动获得父类的::type定义
 */
template <typename T1, typename T2>
struct forward : MyType<T2, T1> // 元函数转发，使用struct的默认public继承,注意参数位置变动
{
}; // 元函数体内无实现代码

/**
 * 元函数转发等价写法
 */
template <typename T1, typename T2>
struct forward_1 // 元函数，不使用转发
{
    typedef typename MyType<T2, T1>::type type; // 调用元函数计算(计算返回什么类型)
};
